package com.suredy.app.porject.export;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.suredy.app.porject.constants.ContractType;
import com.suredy.app.porject.export.model.MaterialContractCountModel;
import com.suredy.app.porject.model.Contract;
import com.suredy.app.porject.model.ContractMoney;
import com.suredy.app.porject.model.sp.Money;
import com.suredy.app.porject.service.ContractSrv;

/**
 * 材料合同台帐统计
 * 
 * @author VIVID.G
 * @since 2016-3-10
 * @version v0.1
 */
@Controller
@RequestMapping("/material-contract-count")
public class MaterialContractCount extends BaseExportorCtrl {

	@Autowired
	private ContractSrv contractSrv;

	// 表头行数
	private final int TITLE_ROWS = 2;

	@RequestMapping(method = RequestMethod.GET)
	public String index(Integer year, Model model) {
		String view = "app/export/material-contract-count";

		if (year == null)
			year = this.getThisYear();

		model.addAttribute("year", year);
		model.addAttribute("data", this.getData(year));

		return view;
	}

	@RequestMapping(value = "/export", method = RequestMethod.GET)
	public void export(Integer year, HttpServletRequest req, HttpServletResponse resp) {
		if (year == null)
			year = this.getThisYear();

		List<MaterialContractCountModel> data = this.getData(year);

		if (data == null || data.isEmpty())
			return;

		this.doExport(year, req, resp, data);
	}

	private void doExport(int year, HttpServletRequest req, HttpServletResponse resp, List<MaterialContractCountModel> data) {
		if (data == null)
			return;

		String fileName = year + "材料合同台帐";

		WritableWorkbook book = null;

		try {
			WritableSheet sheet = null;

			book = this.createWorkbook(req, resp, fileName);

			int indexOfSheet = 0;
			int rowCount = this.TITLE_ROWS;
			int readed = 0;

			do {
				sheet = this.createSheet(book, indexOfSheet++, year);

				if (sheet == null)
					break;

				if (data == null)
					break;

				for (; readed < data.size(); readed++) {
					if (++rowCount > this.MAX_LINE_OF_ONE_SHEET) {
						rowCount = this.TITLE_ROWS;
						break;
					}

					MaterialContractCountModel d = data.get(readed);

					this.writeData(sheet, rowCount - 1, d);
				}
			} while (readed < data.size());

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (book != null) {
				try {
					book.write();
					book.close();
				} catch (Exception e) {
				}
			}
		}
	}

	private WritableSheet createSheet(WritableWorkbook book, int indexOfSheet, int year) throws RowsExceededException, WriteException {
		WritableSheet sheet = super.createSheet(book, indexOfSheet);

		if (sheet == null)
			return null;

		WritableFont t = new WritableFont(WritableFont.ARIAL, 14, WritableFont.BOLD);
		WritableFont h = new WritableFont(WritableFont.ARIAL);
		h.setBoldStyle(WritableFont.BOLD);

		WritableCellFormat title = this.createCellFormat(null, null);
		title.setFont(t);

		WritableCellFormat head = this.createCellFormat(null, null);
		head.setFont(h);

		sheet.mergeCells(0, 0, 13, 0);
		sheet.addCell(new Label(0, 0, year + "材料合同台帐", title));

		sheet.addCell(new Label(0, 1, "序号", head));
		sheet.addCell(new Label(1, 1, "主合同编号", head));
		sheet.addCell(new Label(2, 1, "材料合同编号", head));
		sheet.addCell(new Label(3, 1, "材料合同名称", head));
		sheet.addCell(new Label(4, 1, "供货单位", head));
		sheet.addCell(new Label(5, 1, "合同金额（元）", head));
		sheet.addCell(new Label(6, 1, "结算金额（元）", head));
		sheet.addCell(new Label(7, 1, "付款（元）", head));
		sheet.addCell(new Label(8, 1, "发票开具情况", head));
		sheet.addCell(new Label(9, 1, "挂账情况", head));
		sheet.addCell(new Label(10, 1, "未付金额", head));
		sheet.addCell(new Label(11, 1, "主合同日期", head));
		sheet.addCell(new Label(12, 1, "材料合同日期", head));
		sheet.addCell(new Label(13, 1, "备注", head));

		return sheet;
	}

	private void writeData(WritableSheet sheet, int row, MaterialContractCountModel data) throws RowsExceededException, WriteException {
		if (sheet == null || data == null)
			return;

		int col = 0;

		this.writeCell(sheet, row, col++, row - this.TITLE_ROWS + 1);
		this.writeCell(sheet, row, col++, data.getParentNo());
		this.writeCell(sheet, row, col++, data.getNo());
		this.writeCell(sheet, row, col++, data.getName());
		this.writeCell(sheet, row, col++, data.getCompanyB());
		this.writeCell(sheet, row, col++, data.getPrice());
		this.writeCell(sheet, row, col++, data.getJsPrice());
		this.writeCell(sheet, row, col++, data.getPayoutPrice());
		this.writeCell(sheet, row, col++, data.getInvoiceStatus());
		this.writeCell(sheet, row, col++, data.getGuazhangStatus());
		this.writeCell(sheet, row, col++, data.getLastPrice());
		this.writeCell(sheet, row, col++, data.getParentGq());
		this.writeCell(sheet, row, col++, data.getHtGq());
		this.writeCell(sheet, row, col++, data.getRemark());
	}

	@SuppressWarnings("unchecked")
	private List<MaterialContractCountModel> getData(int year) {
		String ql = "SELECT T, T.parent.no, T.parent.contractStart, T.parent.contractEnd, T.parent.contractDays FROM Contract T WHERE T.type IN (:TYPE) AND ((T.contractStart>=? and T.contractStart<=?) OR (T.contractEnd>=? and T.contractEnd<=?))";
		Date start = this.getYearStart(year);
		Date end = this.getYearEnd(year);

		List<Object> params = new ArrayList<Object>();

		ContractType[] types = new ContractType[] {ContractType.MATERIAL_CONTRACT};

		String TYPE = "";
		for (ContractType t : types) {
			if (!StringUtils.isBlank(TYPE))
				TYPE += ",";

			TYPE += "?";

			params.add(t);
		}
		ql = ql.replace(":TYPE", TYPE);

		params.add(start);
		params.add(end);
		params.add(start);
		params.add(end);

		List<MaterialContractCountModel> ret = new ArrayList<MaterialContractCountModel>();
		int page = 1;

		while (true) {
			List<Object[]> data = (List<Object[]>) this.contractSrv.readByQL(ql, page++, 30, params.toArray());

			if (data == null || data.isEmpty())
				break;

			for (Object[] d : data) {
				MaterialContractCountModel model = this.createModel(d);

				if (model == null)
					continue;

				ret.add(model);
			}
		}

		return ret.isEmpty() ? null : ret;
	}

	private MaterialContractCountModel createModel(Object[] data) {
		if (data == null || data.length != 5)
			return null;

		Contract sub = (Contract) data[0];
		String parentNo = (String) data[1];
		Date parentHtStart = (Date) data[2];
		Date parentHtEnd = (Date) data[3];
		Integer parentHtDays = (Integer) data[4];

		MaterialContractCountModel model = new MaterialContractCountModel();

		model.setParentNo(parentNo);
		model.setNo(sub.getNo());
		model.setName(sub.getName());
		model.setCompanyB(sub.getCompanyB());
		model.setPrice(sub.getPrice());
		model.setJsPrice(sub.getClearingPrice());
		model.setPayoutPrice(this.getPayoutPrice(sub));
		model.setInvoiceStatus(sub.getInvoiceStatus());
		model.setGuazhangStatus(this.getGuazhangStatus(sub));
		model.setParentGq(this.getParentGq(parentHtStart, parentHtEnd, parentHtDays));
		model.setHtGq(this.getHtGq(sub));
		model.setRemark(sub.getRemark());

		return model;
	}

	private Double getPayoutPrice(Contract data) {
		if (data == null || data.getMoney() == null || data.getMoney().isEmpty())
			return null;

		Double ret = null;

		for (Money m : data.getMoney()) {
			if (!m.getPayOut())
				continue;

			// 未到账
			if (!m.getInAccount())
				continue;

			// 需要退回
			if (m.getGaveBack() != null)
				continue;

			if (ret == null)
				ret = 0d;

			ret += m.getTotal();
		}

		return ret;
	}

	private String getGuazhangStatus(Contract data) {
		if (data == null)
			return null;

		ContractMoney money = data.getGzMoney();

		if (money == null || money.getGaveBack() == null)
			return null;

		return money.getGaveBack() ? "已完" : "未完";
	}

	private String getParentGq(Date parentHtStart, Date parentHtEnd, Integer parentHtDays) {
		String gq = "";

		if (parentHtStart != null)
			gq += this.datetimeFormat(parentHtStart, "yyyy.MM.dd");

		if (parentHtEnd != null) {
			if (!StringUtils.isBlank(gq))
				gq += "-";

			gq += this.datetimeFormat(parentHtEnd, "yyyy.MM.dd");
		}

		if (parentHtDays != null) {
			if (!StringUtils.isBlank(gq))
				gq += " ";

			gq += parentHtDays + "天";
		}

		return StringUtils.isBlank(gq) ? null : gq;
	}

	private String getHtGq(Contract data) {
		if (data == null)
			return null;

		String gq = "";

		if (data.getContractStart() != null)
			gq += this.datetimeFormat(data.getContractStart(), "yyyy.MM.dd");

		if (data.getContractEnd() != null) {
			if (!StringUtils.isBlank(gq))
				gq += "-";

			gq += this.datetimeFormat(data.getContractEnd(), "yyyy.MM.dd");
		}

		if (data.getContractDays() != null) {
			if (!StringUtils.isBlank(gq))
				gq += " ";

			gq += data.getContractDays() + "天";
		}

		return StringUtils.isBlank(gq) ? null : gq;
	}

}
